import java.util.Random;
import sun.misc.Unsafe;

public class ReadInt {
	static final int TEST_COUNT = 1000;
	static Unsafe unsafe;

	static {
		try {
			var f = Unsafe.class.getDeclaredField("theUnsafe");
			f.setAccessible(true);
			unsafe = (Unsafe)f.get(null);
		} catch (ReflectiveOperationException e) {
			throw new RuntimeException(e);
		}
	}

	static int SumSafe(byte[] data) {
		var r = 0;
		for (var j = 0; j < TEST_COUNT; j++) {
			for (int i = 0, n = data.length - 4; i < n; i++)
				r += (data[i] & 0xff) + ((data[i + 1] & 0xff) << 8) + ((data[i + 2] & 0xff) << 16) + (data[i + 3] << 24);
		}
		return r;
	}

	static int SumUnsafe(byte[] data) {
		var r = 0;
		for (var j = 0; j < TEST_COUNT; j++) {
			for (int i = 0, n = data.length - 4; i < n; i++)
				r += unsafe.getInt(data, Unsafe.ARRAY_BYTE_BASE_OFFSET + i);
		}
		return r;
	}

	static void test(byte[] data) {
		var t = System.currentTimeMillis();
		var r = SumSafe(data);
		System.out.println("SumSafe  : " + r + ", time: " + (System.currentTimeMillis() - t));

		t = System.currentTimeMillis();
		r = SumUnsafe(data);
		System.out.println("SumUnsafe: " + r + ", time: " + (System.currentTimeMillis() - t));
	}

	public static void main(String[] args) {
		var data = new byte[1 << 20];
		new Random().nextBytes(data);

		test(data);
		test(data);
		test(data);
	}
}
